package com.googlecode.strutson.commands

import com.googlecode.strutson.utils.ConsoleUtils
import com.googlecode.strutson.utils.EnvVariables
import com.googlecode.strutson.utils.TemplateUtils
import org.apache.commons.io.FileUtils
import org.apache.commons.lang.StringUtils
import org.apache.commons.lang.SystemUtils

/**
 * Creates a new web apps from a template (which is hard coded at the moment)
 */
class CreateApp {
    def String MAIN_TEMPLATE = "spring-hibernate-hsql"
    String appName
    String groupId
    String appRoot
    boolean rest;

    void run() {
        appName = readAppName()
        groupId = readRootNamespace();

        def workingDir = SystemUtils.userDir
        def templateArchive = new File("${EnvVariables.HOME}/templates/${MAIN_TEMPLATE}")
        File appDir = new File(workingDir, appName);
        FileUtils.copyDirectory(templateArchive, appDir)

        //process templates
        def bindings = [
                'groupId': groupId,
                'artifactId': appName,
                'rootPackage': groupId,
                'rest': rest
        ]
        TemplateUtils.processAndSave(new File(appDir, 'pom.xml'), bindings)
        TemplateUtils.processAndSave(new File(appDir, 'src/main/resources/applicationContext.xml'), bindings)
        TemplateUtils.processAndSave(new File(appDir, 'src/main/resources/struts.xml'), bindings)

        appRoot = appDir.path
        println "App created under [${appRoot}]"

        //create app dirs (actions, model, services)
        createAppDirs()
    }

    String readAppName() {
        def appName = ConsoleUtils.readLine('Enter the application name: ', {String text ->
            if (StringUtils.isNotBlank(text) && StringUtils.isAlphanumeric(text)) {
                //check if the dir exists already
                if ((new File(SystemUtils.userDir, text)).exists()) {
                    println "Directory [${text}] already exists"
                    return false;
                }

                return true;
            }
            else
                println 'Application Name must contain characters only'
        })

        assert StringUtils.isAlphanumeric(appName);
        return appName;
    }

    String readRootNamespace() {
        def appName = ConsoleUtils.readLine('Enter the application group id(maven groupId, will also ' +
                ' be used as the root package): ', {String text ->
            if (!(text ==~ /^([a-zA-Z_$])+([a-zA-Z_$0-9])*?(\.([a-zA-Z_$])+([a-zA-Z_$0-9])*)*/)) {
                println 'Invalid package name'
                return false
            }
            return true;
        })

        assert StringUtils.isNotBlank(appName);
        return appName;
    }

    void createAppDirs() {
        EnvVariables.setup(appRoot, groupId)
        [
                EnvVariables.MODELS_DIR,
                EnvVariables.ACTIONS_DIR,
                EnvVariables.SERVICES_DIR,
                EnvVariables.SERVICES_IMPL_DIR
        ].each {
            println "Creating dir [${it}]"
            (new File(it)).mkdirs()
        }
    }
}